-/*
- * xen performance counters
- */
#include <xeno/lib.h>
#include <xeno/smp.h>
#include <xeno/perfc.h>
#include <xeno/keyhandler.h>
-/* used for different purposes in perfc.h and here */
-#undef PERFCOUNTER
-#undef PERFCOUNTER_CPU
-#undef PERFCOUNTER_ARRAY
-
-#define PERFCOUNTER( var, name ) "[0]"name"\0",
-#define PERFCOUNTER_CPU( var, name ) "C"name"\0",
-#define PERFCOUNTER_ARRAY( var, name, size ) "["#size"]"name"\0",
-
-char* perfc_name[] = {
+#undef PERFCOUNTER
+#undef PERFCOUNTER_CPU
+#undef PERFCOUNTER_ARRAY
+#define PERFCOUNTER( var, name ) { name, TYPE_SINGLE, 0 },
+#define PERFCOUNTER_CPU( var, name ) { name, TYPE_CPU, 0 },
+#define PERFCOUNTER_ARRAY( var, name, size ) { name, TYPE_ARRAY, size },
+static struct {
+ char *name;
+ enum { TYPE_SINGLE, TYPE_CPU, TYPE_ARRAY } type;
+ int nr_elements;
+} perfc_info[] = {
#include <xeno/perfc_defn.h>
};
-struct perfcounter_t perfcounters;
+#define NR_PERFCTRS (sizeof(perfc_info) / sizeof(perfc_info[0]))
-void __perfc_print (unsigned long counter[], int offset)
-{
- int loop;
- int total_size = 0;
- int element_size = 0;
- int cpus = 0;
- int num = 0;
-
- for (loop = 0; loop < sizeof(perfc_name) / sizeof(char *); loop++) {
- if (perfc_name[loop][0] == 'C') {
- element_size = NR_CPUS;
- cpus = 1;
- } else {
- num = sscanf (perfc_name[loop], "[%d]", &element_size);
- }
-
- total_size += element_size == 0 ? 1 : element_size;
- if (total_size > offset) break;
- }
- if (loop == sizeof(perfc_name) / sizeof(char *)) {
- printf ("error: couldn't find variable\n");
- return;
- }
- if (element_size == 0) { /* single counter */
- printf ("%10lu 0x%08lx %s\n", counter[0], counter[0],
- perfc_name[loop] + 2 + num);
- } else if (cpus) { /* counter per CPU */
- for (loop = 0; loop < smp_num_cpus; loop++) {
- printf ("%10lu 0x%08lx cpu[%02d] %s\n",
- counter[loop], counter[loop],
- loop, perfc_name[loop]);
- }
-
- } else { /* show entire array */
- for (loop = 0; loop < element_size; loop++) {
- printf ("%10lu 0x%08lx %s:%d\n",
- counter[loop], counter[loop],
- perfc_name[loop] + 2 + num, loop);
- }
- }
- return;
-}
+struct perfcounter_t perfcounters;
-void perfc_printall (u_char key, void *dev_id, struct pt_regs *regs)
+void perfc_printall(u_char key, void *dev_id, struct pt_regs *regs)
{
- int loop, idx;
- int element_size;
- int cpus=0;
- int num = 0;
+ int i, j;
s_time_t now = NOW();
unsigned long *counters = (unsigned long *)&perfcounters;
- printf ("xen performance counters: now=0x%08X%08X\n",
- (u32)(now>>32), (u32)now);
-
- for (loop = 0; loop < sizeof(perfc_name) / sizeof(char *); loop++) {
-
- if (perfc_name[loop][0] == 'C') {
- element_size = NR_CPUS;
- cpus = 1;
- } else {
- num = sscanf (perfc_name[loop], "[%d]", &element_size);
- }
-
- for (idx = 0; idx < (element_size ? element_size : 1); idx++) {
- if (cpus) {
- if (idx < smp_num_cpus)
- printf ("%10ld 0x%08lx cpu[%02d] %s\n",
- *counters, *counters, idx, perfc_name[loop] + 1);
- } else if (element_size) {
- printf ("%10ld 0x%08lx %s:%d\n",
- *counters, *counters, perfc_name[loop] + num + 2, idx);
- } else {
- printf ("%10ld 0x%08lx %s\n",
- *counters, *counters, perfc_name[loop] + num + 2);
- }
- counters++;
+ printk("Xen performance counters SHOW (now = 0x%08X:%08X)\n",
+ (u32)(now>>32), (u32)now);
+
+ for ( i = 0; i < NR_PERFCTRS; i++ )
+ {
+ switch ( perfc_info[i].type )
+ {
+ case TYPE_SINGLE:
+ printk("%10ld 0x%08lx %s\n",
+ counters[0], counters[0], perfc_info[i].name);
+ counters += 1;
+ break;
+ case TYPE_CPU:
+ for ( j = 0; j < smp_num_cpus; j++ )
+ printk("%10ld 0x%08lx %s[CPU %02d]\n",
+ counters[j], counters[j], perfc_info[i].name, j);
+ counters += j;
+ break;
+ case TYPE_ARRAY:
+ for ( j = 0; j < perfc_info[i].nr_elements; j++ )
+ printk("%10ld 0x%08lx %s[ARR %02d]\n",
+ counters[j], counters[j], perfc_info[i].name, j);
+ counters += j;
+ break;
}
}
-
- //perfc_reset( key, dev_id, regs );
-
- return;
}
-void perfc_reset (u_char key, void *dev_id, struct pt_regs *regs)
+void perfc_reset(u_char key, void *dev_id, struct pt_regs *regs)
{
s_time_t now = NOW();
- printk ("xen performance counters reset: now=0x%08X%08X\n",
- (u32)(now>>32), (u32)now);
- memset (&perfcounters, 0, sizeof(perfcounters));
+ printk("Xen performance counters RESET (now = 0x%08X:%08X)\n",
+ (u32)(now>>32), (u32)now);
+ memset(&perfcounters, 0, sizeof(perfcounters));
}
return i;
}
-/**
- * vsscanf - Unformat a buffer into a list of arguments
- * @buf: input buffer
- * @fmt: format of buffer
- * @args: arguments
- */
-int vsscanf(const char * buf, const char * fmt, va_list args)
-{
- const char *str = buf;
- char *next;
- int num = 0;
- int qualifier;
- int base;
- int field_width = -1;
- int is_sign = 0;
-
- while(*fmt && *str) {
- /* skip any white space in format */
- /* white space in format matchs any amount of
- * white space, including none, in the input.
- */
- if (isspace(*fmt)) {
- while (isspace(*fmt))
- ++fmt;
- while (isspace(*str))
- ++str;
- }
-
- /* anything that is not a conversion must match exactly */
- if (*fmt != '%' && *fmt) {
- if (*fmt++ != *str++)
- break;
- continue;
- }
-
- if (!*fmt)
- break;
- ++fmt;
-
- /* skip this conversion.
- * advance both strings to next white space
- */
- if (*fmt == '*') {
- while (!isspace(*fmt) && *fmt)
- fmt++;
- while (!isspace(*str) && *str)
- str++;
- continue;
- }
-
- /* get field width */
- if (isdigit(*fmt))
- field_width = skip_atoi(&fmt);
-
- /* get conversion qualifier */
- qualifier = -1;
- if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || *fmt == 'Z') {
- qualifier = *fmt;
- fmt++;
- }
- base = 10;
- is_sign = 0;
-
- if (!*fmt || !*str)
- break;
-
- switch(*fmt++) {
- case 'c':
- {
- char *s = (char *) va_arg(args,char*);
- if (field_width == -1)
- field_width = 1;
- do {
- *s++ = *str++;
- } while(field_width-- > 0 && *str);
- num++;
- }
- continue;
- case 's':
- {
- char *s = (char *) va_arg(args, char *);
- if(field_width == -1)
- field_width = INT_MAX;
- /* first, skip leading white space in buffer */
- while (isspace(*str))
- str++;
-
- /* now copy until next white space */
- while (*str && !isspace(*str) && field_width--) {
- *s++ = *str++;
- }
- *s = '\0';
- num++;
- }
- continue;
- case 'n':
- /* return number of characters read so far */
- {
- int *i = (int *)va_arg(args,int*);
- *i = str - buf;
- }
- continue;
- case 'o':
- base = 8;
- break;
- case 'x':
- case 'X':
- base = 16;
- break;
- case 'd':
- case 'i':
- is_sign = 1;
- case 'u':
- break;
- case '%':
- /* looking for '%' in str */
- if (*str++ != '%')
- return num;
- continue;
- default:
- /* invalid format; stop here */
- return num;
- }
-
- /* have some sort of integer conversion.
- * first, skip white space in buffer.
- */
- while (isspace(*str))
- str++;
-
- if (!*str || !isdigit(*str))
- break;
-
- switch(qualifier) {
- case 'h':
- if (is_sign) {
- short *s = (short *) va_arg(args,short *);
- *s = (short) simple_strtol(str,&next,base);
- } else {
- unsigned short *s = (unsigned short *) va_arg(args, unsigned short *);
- *s = (unsigned short) simple_strtoul(str, &next, base);
- }
- break;
- case 'l':
- if (is_sign) {
- long *l = (long *) va_arg(args,long *);
- *l = simple_strtol(str,&next,base);
- } else {
- unsigned long *l = (unsigned long*) va_arg(args,unsigned long*);
- *l = simple_strtoul(str,&next,base);
- }
- break;
- case 'L':
- if (is_sign) {
- long long *l = (long long*) va_arg(args,long long *);
- *l = simple_strtoll(str,&next,base);
- } else {
- unsigned long long *l = (unsigned long long*) va_arg(args,unsigned long long*);
- *l = simple_strtoull(str,&next,base);
- }
- break;
- case 'Z':
- {
- size_t *s = (size_t*) va_arg(args,size_t*);
- *s = (size_t) simple_strtoul(str,&next,base);
- }
- break;
- default:
- if (is_sign) {
- int *i = (int *) va_arg(args, int*);
- *i = (int) simple_strtol(str,&next,base);
- } else {
- unsigned int *i = (unsigned int*) va_arg(args, unsigned int*);
- *i = (unsigned int) simple_strtoul(str,&next,base);
- }
- break;
- }
- num++;
-
- if (!next)
- break;
- str = next;
- }
- return num;
-}
-
-/**
- * sscanf - Unformat a buffer into a list of arguments
- * @buf: input buffer
- * @fmt: formatting of buffer
- * @...: resulting arguments
- */
-int sscanf(const char * buf, const char * fmt, ...)
-{
- va_list args;
- int i;
-
- va_start(args,fmt);
- i = vsscanf(buf,fmt,args);
- va_end(args);
- return i;
-}